package scala.Implicit.Conversion

object AnotherExample {
   def main(args: Array[String]): Unit = {

   }

   //define implicit object
   implicit object MonoInt extends MonoID[Int] {
      def add(x: Int, y: Int): Int = x + y
      def unit: Int = 0
   }

   implicit object MonoString extends MonoID[String] {
      def add(x: String, y: String) = x.concat(y)
      def unit = ""
   }

   def sum[A](xs: List[A])(implicit m: MonoID[A]): A = {
      xs match {
         case List() => m.unit
         case head :: tail => {
            m.add(head, sum(tail))
         }
      }
   }
   val a = List(1, 2, 3, 4, 5)
   val b = List("a", "b", "c")
   val c = sum(a)
   val d = sum(b)
   println(c)
   println(d)
}

abstract class SemiGroup[A] {
   def add(x: A, y: A): A
}

abstract class MonoID[A] extends SemiGroup[A] {
   def unit: A
}

